extern "C" {

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>

}

#include <SDL2/SDL.h>
#include <SDL2/SDL_thread.h>

#include <iostream>

#include "PacketQueue.h"
#include "Audio.h"
#include "Media.h"
#include "VideoDisplay.h"
using namespace std;

bool quit = false;

struct {
    bool isDump = false;
    bool isPlay = false;

    char file_name[256] = {0};

    int videoChannel = -1;
    int audioChannel = -1;
    int subtitleChannel = -1;
} mArgs;

void usage() {
    const char usage[256] =
            "Usage: FsPlayer dump/play <file> [options]\n"
            "  options:\n"
            "    -video <channel-id>: play video for channel id\n"
            "    -audio <channel-id>: play audio for channel id\n"
            "    -sub <channel-id>: play subtitle for channel id\n";
    printf("%s\n", usage);
}

bool parse_args(int argv, char *args[]) {
    if (argv <= 1 || args == nullptr) {
        return false;
    }

    if (!strcmp("dump", args[1])) {
        mArgs.isDump = true;
    } else if (!strcmp("play", args[1])) {
        mArgs.isPlay = true;
    }

    if (argv >= 3) {
        strcpy(mArgs.file_name, args[2]);
    }

    //Not for dump
    if (argv > 3 && mArgs.isPlay) {
        for (int i = 3; i < argv; ++i) {
            printf("%s ", args[i]);

            if (!strcmp("-video", args[i]) && argv > (i + 1)) {
                mArgs.videoChannel = atoi(args[++i]);
            } else if (!strcmp("-audio", args[i]) && argv > (i + 1)) {
                mArgs.audioChannel = atoi(args[++i]);
            } else if (!strcmp("-sub", args[i]) && argv > (i + 1)) {
                mArgs.subtitleChannel = atoi(args[++i]);
            }
        }
    }

    printf("\n");
    return true;
}


int main(int argv, char* argc[])
{

	if (!parse_args(argv, argc)) {
	    usage();
        return 0;
	}

//    printf("struct {\n"
//           "    bool isDump = %d;\n"
//           "    bool isPlay = %d;\n"
//           "\n"
//           "    char file_name[256] = %s;\n"
//           "\n"
//           "    int videoChannel = %d;\n"
//           "    int audioChannel = %d;\n"
//           "    int subtitleChannel = %d;\n"
//           "}", mArgs.isDump, mArgs.isPlay, mArgs.file_name,
//           mArgs.videoChannel, mArgs.audioChannel, mArgs.subtitleChannel);

	av_register_all();

	if (mArgs.isDump) {
	    MediaState::GlobalDump(mArgs.file_name);
        return 0;
	} else if (!mArgs.isPlay) {
	    printf("error: Must be dump or play.\n");
        return -1;
	}

	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);

	char* filename = mArgs.file_name;
	MediaState media(filename, mArgs.audioChannel, mArgs.videoChannel, mArgs.subtitleChannel);

	if (!media.openInput())
        return -1;

	SDL_CreateThread(decode_thread, "", &media); // ���������̣߳���ȡpacket�������л���

	media.audio->audio_play(); // create audio thread
	media.video->video_play(&media); // create video thread

	AVStream *audio_stream = media.pFormatCtx->streams[media.audio->stream_index];
	AVStream *video_stream = media.pFormatCtx->streams[media.video->stream_index];

	double audio_duration = audio_stream->duration * av_q2d(audio_stream->time_base);
	double video_duration = video_stream->duration * av_q2d(video_stream->time_base);

	cout << "audioʱ����" << audio_duration << endl;
	cout << "videoʱ����" << video_duration << endl;

	SDL_Event event;
	while (true) // SDL event loop
	{
		SDL_WaitEvent(&event);
		switch (event.type)
		{
		case FF_QUIT_EVENT:
		case SDL_QUIT:
			quit = 1;
			SDL_Quit();

			return 0;
			break;

		case FF_REFRESH_EVENT:
			video_refresh_timer(&media);
			break;

		default:
			break;
		}
	}

	getchar();
	return 0;
}